package com.xhwl.centiotdata.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.handler.weigh.WeighIntegrationFactory;
import com.xhwl.centiotdata.handler.weigh.WeighIntegrationHandler;
import com.xhwl.centiotdata.integration.vehicleschedule.VehicleScheduleFactory;
import com.xhwl.centiotdata.integration.vehicleschedule.VehicleScheduleIntegrationConfig;
import com.xhwl.centiotdata.integration.vehicleschedule.VehicleScheduleSystemHandler;
import com.xhwl.centiotdata.pojo.dto.weigh.WeighConfigDTO;
import com.xhwl.centiotdata.service.cent.IDeviceCentService;
import com.xhwl.centiotdata.service.cent.IMnProgramService;
import com.xhwl.centiotdata.service.cent.ISpaceCentService;
import com.xhwl.centiotdata.service.impl.BoardcastServiceImpl;
import com.xhwl.centiotdata.service.integrateconfig.WeighIntegrationConfig;
import com.xhwl.centiotdata.utils.ThreadPoolUtils;
import com.xhwl.common.dto.cent.device.DeviceDTO;
import com.xhwl.common.dto.cent.iotdata.haikang.BroadcastDTO;
import com.xhwl.common.dto.cent.iotdata.vehicleschedule.VehicleScheduleRequestsDTO;
import com.xhwl.common.dto.cent.iotdata.weighbridge.WeighbridgeDTO;
import com.xhwl.common.dto.cent.zone.MnProgramDisplayDTO;
import com.xhwl.common.enums.CategoryEnum;
import com.xhwl.common.pojo.ResultBuilder;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.sdata.Organization;
import com.xhwl.common.pojo.cent.sdata.OrganizationType;
import com.xhwl.common.query.cent.device.DevicePageQuery;
import com.xhwl.common.query.cent.device.DeviceQuery;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * 梅特勒-托利多 地磅回调
 *
 * @author pengjunming
 * @description
 * @date 2022/9/28 16:16
 */
@RestController
@Slf4j
public class WeighbridgeController {

    @Resource
    private IMnProgramService iMnProgramService;


    @Resource
    private VehicleScheduleFactory vehicleScheduleFactory;

    @Resource
    private IDeviceCentService iDeviceCentService;

    @Autowired
    private WeighIntegrationConfig weighIntegrationConfig;

    @Autowired
    private ISpaceCentService spaceCentService;

    @Autowired
    private BoardcastServiceImpl boardcastService;

    /**
     * 称重回调
     *
     * @param dto
     */
    @PostMapping("/v1/weighbridge/callback")
    public ResultJson<String> handleWeight(@RequestBody WeighbridgeDTO dto) {
        ThreadPoolUtils.executor.execute(() -> this.handleData(dto));
        return ResultBuilder.success("Success");
    }

    private void handleData(WeighbridgeDTO dto) {
        log.info("地磅回调请求数据:{}", JSON.toJSONString(dto));

        Map<Integer, List<WeighConfigDTO>> integrationConfigMap2 = weighIntegrationConfig.getIntegrationConfig();
        integrationConfigMap2.forEach(
                (key, value) -> {
                    if (!value.isEmpty()) {
                        value.forEach(integrationConfig -> {
                            dto.setProjectId(integrationConfig.getProjectId());
                            DevicePageQuery deviceQuery = new DevicePageQuery();
                            deviceQuery.setProjectId(dto.getProjectId());
                            deviceQuery.setCategoryId(CategoryEnum.WEIGHBRIDGE_SYSTEM.getId());
                            List<DeviceDTO> deviceDTOS = iDeviceCentService.listDevice(null, deviceQuery);
                            try {
                                //获取点位信息
                                if(!CollectionUtils.isEmpty(deviceDTOS)){
                                   this.weighForOrd(deviceDTOS.get(0).getOrganizationId(), dto);
                                }
                                //判断地磅上传的重量是多少，如果等于0kg就不同步给车辆调度
                                int weight = Integer.parseInt(dto.getWeight());
                                if(weight >= integrationConfig.getWeightLimit()){
                                    // 同步称重结果给车辆调度系统
                                    log.info("地磅上重量大于{}kg，需同步到车辆调度", integrationConfig.getWeightLimit());
                                    List<VehicleScheduleIntegrationConfig> configs = vehicleScheduleFactory.onFindingIntegrationConfigs(dto.getProjectId());
                                    for (VehicleScheduleIntegrationConfig config : configs) {
                                        VehicleScheduleSystemHandler handlers = vehicleScheduleFactory.onFindingIntegrationHandler(config.getProductName());
                                        VehicleScheduleRequestsDTO request = new VehicleScheduleRequestsDTO();
                                        BeanUtils.copyProperties(dto, request);
                                        handlers.onSyncingWeighResult(config, request);
                                    }
                                }else{
                                    log.info("本次称重结果小于{}kg，开始联动播放音柱", integrationConfig.getWeightLimit());
                                    BroadcastDTO broadcastDTO = new BroadcastDTO();
                                    broadcastDTO.setProjectId(integrationConfig.getProjectId());
                                    broadcastDTO.setPositionId(integrationConfig.getWeightLimitYinZhu());
                                    broadcastDTO.setMessageContent("检测无效，请重新上磅");
                                    log.info("请求音柱的请求参数为：{}", JSONObject.toJSONString(broadcastDTO));
                                    ResultJson broadcast = boardcastService.broadcast(broadcastDTO);
                                    log.info("请求音柱的返回结果为：{}", JSONObject.toJSONString(broadcast));
                                }
                            } catch (Exception e) {
                                log.error("地磅回调推送车辆调度系统失败", e);
                            }

                            //和信息发布联动的代码可能还需要修改
                            try {
                                if (!CollectionUtils.isEmpty(deviceDTOS)) {
                                    DeviceDTO deviceDTO = deviceDTOS.get(0);
                                    Integer organizationId = deviceDTO.getOrganizationId();
                                    deviceQuery.setOrganizationId(organizationId);
                                }
                                deviceQuery.setCategoryId(CategoryEnum.INFO_SYSTEM.getId());
                                List<DeviceDTO> infoDevices = iDeviceCentService.listDevice(null, deviceQuery);
                                if (!CollectionUtils.isEmpty(infoDevices)) {
                                    DeviceDTO infoDevice = infoDevices.get(0);
                                    //信息发布
                                    MnProgramDisplayDTO mnProgramDisplayDTO = new MnProgramDisplayDTO();
                                    mnProgramDisplayDTO.setPositionId(this.orgIdToOrgCode(infoDevice.getOrganizationId()));
                                    mnProgramDisplayDTO.setSerialNumber(infoDevice.getThirdDeviceId());
                                    String content = dto.getWeighTime() + ",业务单号:" + dto.getTransportOrderCode() + ",车牌号" + dto.getTruckNo()
                                            + "本次称重结果:" + dto.getWeight() + dto.getUnit();
                                    mnProgramDisplayDTO.setDisplayContent(content);
                                    ResultJson resultJson = iMnProgramService.playTextProgram(mnProgramDisplayDTO);
                                    if (!resultJson.getState()) {
                                        log.error("信息发布失败,{}", resultJson.getMessage());
                                    }
                                }
                            } catch (Exception e) {
                                log.error("地磅回调处理异常", e);
                            }
                        });
                    }
                }
        );
    }

    /**
     * 通过组织id获取组织编码信息
     */
    private String orgIdToOrgCode(Integer orgId){
        if(orgId == null){
            log.error("orgIdToOrgCode方法中传的orgId参数为空");
            return null;
        }
        Organization organization = spaceCentService.getById(orgId);
        //由于space类型的组织的编码不是存储在组织表中，而是存储在space表中
        if(!StringUtils.isEmpty(organization.getCode())){
            return organization.getCode();
        }else{
            ResultJson spaceResult = spaceCentService.detail(null, organization.getId());
            log.info("组织表里面没有code信息，请求space结果为：{}，", JSONObject.toJSONString(spaceResult));
            if (spaceResult == null || !spaceResult.getState()){
                log.error("获取space信息失败");
                return null;
            }
            JSONObject spaceObject = JSONObject.parseObject(
                    JSONObject.parseObject(JSONObject.toJSONString(spaceResult.getResult())).getString("data"));
            if(StringUtils.isEmpty(spaceObject.getString("code"))){
                log.error("space中没有code信息");
                return null;
            }
            return spaceObject.getString("code");
        }
    }

    /**
     * 为称重结果赋值点位信息
     */
    private void weighForOrd(Integer orgId, WeighbridgeDTO weighbridgeDTO){
        if(orgId == null){
            log.error("orgIdToOrgCode方法中传的orgId参数为空");
            return;
        }
        Organization organization = spaceCentService.getById(orgId);
        //由于space类型的组织的编码不是存储在组织表中，而是存储在space表中
        if(!StringUtils.isEmpty(organization.getCode())){
            weighbridgeDTO.setPositionId(organization.getCode());
        }else{
            ResultJson spaceResult = spaceCentService.detail(null, organization.getId());
            log.info("组织表里面没有code信息，请求space结果为：{}，", JSONObject.toJSONString(spaceResult));
            if (spaceResult == null || !spaceResult.getState()){
                log.error("获取space信息失败");
                return;
            }
            JSONObject spaceObject = JSONObject.parseObject(
                    JSONObject.parseObject(JSONObject.toJSONString(spaceResult.getResult())).getString("data"));
            if(StringUtils.isEmpty(spaceObject.getString("code"))){
                log.error("space中没有code信息");
                return;
            }
            weighbridgeDTO.setPositionId(spaceObject.getString("code"));
        }
        weighbridgeDTO.setPositionName(organization.getName());
        List<OrganizationType> organizationTypeList = spaceCentService.getOrgTypeList(null);
        organizationTypeList.stream().filter(organizationType1 -> organizationType1.getId().equals(organization.getType()))
                .findAny().ifPresent(organizationType -> weighbridgeDTO.setPositionType(organizationType.getCode()));
    }
}
